﻿using System;
using System.Linq;
using System.Web.Mvc;
using FShare.DataModel;
using FShare.Models;
using FShare.Helpers;
using FShare.Classes;
using FShare.ViewModels;
using System.Data;
using System.Web.Security;
using System.Collections.Generic;

namespace FShare.Controllers
{
    public class FilesController : Controller
    {
        public ActionResult Index()
        {
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Upload()
        {
            return RedirectToAction("Index", "Home");
        }

        /// <summary>
        /// Uploads a file to the service
        /// </summary>
        /// <param name="model">the model</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Upload(FileUploadModel model)
        {
            string groupKey = Utils.GenerateSecret();
            var fileList = new List<FShareFile>();
            using (var context = new FShareDataModelContainer())
            {
                for (int i = 0; i < Request.Files.Count; i++)
                {
                    var file = Request.Files[i];
                    if (file != null)
                    {
                        string downloadLocation = FileService.SaveFile(file);

                        var fshareFile = new FShareFile()
                        {
                            Id = Guid.NewGuid(),
                            DateUploaded = DateTime.Now,
                            DeleteSecret = Utils.GenerateSecret(),
                            Description = model.Description,
                            DestinationEmail = model.Email,
                            DownloadLocation = downloadLocation,
                            DownloadSecret = Utils.GenerateSecret(),
                            GroupKey = groupKey,
                            Name = file.FileName,
                            NumberOfDownloads = 0,
                            Size = file.ContentLength,
                        };

                        var currentUser = Membership.GetUser();
                        if (currentUser != null)
                        {
                            fshareFile.UploaderGuid = Guid.Parse(currentUser.ProviderUserKey.ToString());
                        }
                        context.FShareFiles.AddObject(fshareFile);
                        fileList.Add(fshareFile);
                    }
                }

                context.SaveChanges();
            }

            if (!string.IsNullOrEmpty(model.Email) && fileList.Count > 0)
            {
                MailService.SendLinks(fileList, model.Email);
            }

            return RedirectToAction("Display", new { id = groupKey });
        }

        /// <summary>
        /// Displays the links for download and delete for the file group
        /// </summary>
        /// <param name="id">code of the file group</param>
        /// <returns></returns>
        public ActionResult Display(string id)
        {
            using (var context = new FShareDataModelContainer())
            {
                var files = context.FShareFiles.Where(f => f.GroupKey == id).ToList();
                var model = new DisplayViewModel
                {
                    Files = files
                };

                return View(model);
            }
        }

        /// <summary>
        /// Creates a download page for the selected file
        /// </summary>
        /// <param name="id">the download secret</param>
        /// <returns></returns>
        public ActionResult Download(string id)
        {
            DownloadViewModel model = null;
            using (var context = new FShareDataModelContainer())
            {
                var file = context.FShareFiles.Where(f => f.DownloadSecret == id).FirstOrDefault();
                if (!(file == null || file.IsDeleted))
                {
                    model = new DownloadViewModel
                    {
                        DateUploaded = file.DateUploaded,
                        DownloadFileName = file.Name,
                        DownloadFileSize = file.Size,
                        DownloadSecret = id,
                        DownloadsCount = file.NumberOfDownloads
                    };

                    context.ObjectStateManager.ChangeObjectState(file, EntityState.Modified);
                    context.SaveChanges();
                }
            }
            return View(model);
        }

        /// <summary>
        /// Downloads a file to the client
        /// </summary>
        /// <param name="id">download secret</param>
        /// <returns>Redirect to the actual file on the file system</returns>
        public ActionResult DownloadFile(string id)
        {
            RedirectResult result = null;
            using (var context = new FShareDataModelContainer())
            {
                var file = context.FShareFiles.Where(f => f.DownloadSecret == id).FirstOrDefault();
                if (!(file == null || file.IsDeleted))
                {
                    string filePath = new Uri(string.Format("{0}{1}", Request.Url.GetLeftPart(UriPartial.Authority), file.DownloadLocation)).ToString();
                    result = new RedirectResult(filePath);
                    file.NumberOfDownloads += 1;
                    context.ObjectStateManager.ChangeObjectState(file, System.Data.EntityState.Modified);
                    context.SaveChanges();
                }
            }
            return result;
        }

        /// <summary>
        /// Deletes a file specified by it's delete secret
        /// </summary>
        /// <param name="id">the delete secret</param>
        /// <returns></returns>
        public ActionResult Delete(string id)
        {
            var model = new DeleteFileViewModel();
            using (var context = new FShareDataModelContainer())
            {
                var file = context.FShareFiles.Where(f => f.DeleteSecret == id).FirstOrDefault();
                if (file == null)
                {
                    model.WasDeleted = true;
                }
                else
                {
                    if (!file.IsDeleted)
                    {
                        file.IsDeleted = FileService.DeleteFile(file.DownloadLocation);
                        model.FileName = file.Name;
                        model.IsDeleted = file.IsDeleted;
                        model.UploadDate = file.DateUploaded;
                    }
                    else
                    {
                        file.IsDeleted = true;
                    }
                }

                context.ObjectStateManager.ChangeObjectState(file, System.Data.EntityState.Modified);
                context.SaveChanges();
            }
            return View(model);
        }
    }
}
